package com.open.spring.utils.soap;

import org.springframework.ws.WebServiceMessage;
import org.springframework.ws.client.core.FaultMessageResolver;
import org.springframework.ws.soap.SoapFaultDetail;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.client.SoapFaultClientException;

import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.StringWriter;

/**
 * @author PengCheng
 * @date 2017-08-24
 */
public class SoapFaultResolver implements FaultMessageResolver {
    private final TransformerFactory tfactory = TransformerFactory.newInstance();

    @Override
    public void resolveFault(WebServiceMessage message) throws IOException {
        SoapFaultClientException faultException = new SoapFaultClientException((SoapMessage) message);
        String faultDetail = extractFaultDetail(faultException);

        System.out.println(faultDetail);

        if (faultDetail.contains("HibernateOptimisticLockingFailureException")) {
//            throw new OptimisticLockingFailureException(faultException);
        } else {
            throw faultException;
        }
    }

    public String extractFaultDetail(SoapFaultClientException faultException) {
        final SoapFaultDetail faultDetail = faultException.getSoapFault().getFaultDetail();
        return srcToString(faultDetail.getSource());
    }

    private String srcToString(Source s) {
        try {
            return transformToString(s);
        } catch (TransformerException e) {
            throw new RuntimeException(e);
        }
    }

    private String transformToString(Source s) throws TransformerFactoryConfigurationError,
            TransformerException {
        StringWriter writer = new StringWriter();
        Result r = new StreamResult(writer);
        Transformer xform;
        xform = tfactory.newTransformer();
        xform.transform(s, r);
        return writer.toString();
    }
}
